package com.fuyun.microservice.codec;

import com.fuyun.microservice.codec.msg.BroadRequestMessage;
import com.fuyun.microservice.codec.msg.Header;
import com.fuyun.microservice.codec.msg.Message;
import com.fuyun.microservice.utils.BufferUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageCodec;
import io.netty.util.ReferenceCountUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;

import java.util.List;

@Slf4j
@ChannelHandler.Sharable
public class BroadRequestMessageCodes extends MessageToMessageCodec<Message, BroadRequestMessage> {
    private static final int KEY_LENGTH = 32;

    @Override
    protected void encode(ChannelHandlerContext ctx, BroadRequestMessage msg, List<Object> out) throws Exception {
        byte[] bodyBytes = msg.getBody().getBytes(BufferUtil.ENCODE_CHARSET);
        int contentLength = 5 +KEY_LENGTH+ bodyBytes.length;
        ByteBuf bodyBuffer = Unpooled.buffer(contentLength);
        bodyBuffer.writeInt(msg.getType());
        bodyBuffer.writeByte(msg.getShouldAck());

        byte[] keyBytes = BufferUtil.toFixedBytes(msg.getTopic(), KEY_LENGTH);
        bodyBuffer.writeBytes(keyBytes);

        bodyBuffer.writeBytes(bodyBytes);

        msg.setBodyBuffer(bodyBuffer.array());
        ReferenceCountUtil.release(bodyBuffer);
        out.add(msg);
    }

    @Override
    protected void decode(ChannelHandlerContext ctx, Message msg, List<Object> out) {
        Header header = msg.getHeader();
        if (header.getCommandId() != PacketType.BROADREQUEST.getCommandId()) {
            out.add(msg);
            return;
        }

        BroadRequestMessage broadRequestMessage = new BroadRequestMessage();
        BeanUtils.copyProperties(msg, broadRequestMessage);
        ByteBuf bodyBuffer = Unpooled.wrappedBuffer(msg.getBodyBuffer());
        broadRequestMessage.setType(bodyBuffer.readInt());
        broadRequestMessage.setShouldAck(bodyBuffer.readByte());

        String key = BufferUtil.readStringExcludeEmpty(BufferUtil.toByteArraySafe(bodyBuffer.readBytes(KEY_LENGTH)));
        broadRequestMessage.setTopic(key);

        int paramsLength = header.getBodyLength() - (HeaderCodec.HEADER_LENGTH + 5 + KEY_LENGTH);
        String body = new String(BufferUtil.toByteArraySafe(bodyBuffer.readBytes(paramsLength)), BufferUtil.CHARSET_DEFAULT);
        broadRequestMessage.setBody(body);

        ReferenceCountUtil.release(bodyBuffer);
        out.add(broadRequestMessage);
    }
}
